package com.om.exposed;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.Test;

/**
 * Run this with the following JVM arguments to invoke contest:
 * -javaagent:../commonlibs/ConTest.jar
 * -Dcontest.preferences=../commonlibs/KingProperties
 */

public class ValueWithObjectTest {
    private static final int THREADS = 2;
    private static final int LOOPS = 10;
    ObjectWithValue object;

    @Before
    public void init() {
        object = new ObjectWithValue();
        // object = new ObjectWithValue() {
        //
        // @Override
        // public void incrementValue() {
        // try {
        // Thread.sleep(1);
        // } catch (InterruptedException e) {
        // // TODO Auto-generated catch block
        // e.printStackTrace();
        // }
        // super.incrementValue();
        // }
        // };
        // };
    }

    Runnable incrementValue = new Runnable() {
        public void run() {
            for (int i = 0; i < LOOPS; ++i)
                object.incrementValue();
        }
    };

    @Test
    public void singleThreaded() throws InterruptedException {
        Thread t = new Thread(incrementValue);
        t.start();
        t.join();
        assertEquals(LOOPS, object.getValue());
    }

    @Test
    public void demonstrateMultipleThreadsFail() throws InterruptedException {
        Thread[] threads = new Thread[THREADS];

        for (int i = 0; i < threads.length; ++i)
            threads[i] = new Thread(incrementValue);

        for (Thread t : threads)
            t.start();
        for (Thread t : threads)
            t.join();

        int expected = LOOPS * THREADS;
        String message = String.format("Correct value: %d, actual value: %d", expected, object.getValue());
        assertTrue(message, expected != object.getValue());
        System.out.println(message);
    }
}
